package com.android.task4;

public class Point extends Object {
	protected int mY;
	protected int mX;

	public Point(int y, int x) {
		this.mY = y;
		this.mX = x;
	}

	public Point(Point p) {
		this.mY = p.mY;
		this.mX = p.mX;
	}

	public int getY() {
		return this.mY;
	}

	public int getMapTileLatitude() {
		return this.mY;
	}

	public int getX() {
		return this.mX;
	}

	public int getMapTileLongitude() {
		return this.mX;
	}

	@Override
	public String toString() {
		return "Point[" + "y=" + this.mY + ";x=" + this.mX + "]";
	}

	public Point withTranslation(final int deltaY, final int deltaX) {
		return new Point(this.mY + deltaY, this.mX + deltaX);
	}

	public Point withAntiTranslation(final int deltaY, final int deltaX) {
		return new Point(this.mY - deltaY, this.mX - deltaX);
	}

	public Point withTranslationMod(final int deltaY, final int deltaX,
			final int zoomLevel) {
		final int mapTileUpperBound = 1 << zoomLevel;
		return new Point(mod(this.mY + deltaY, mapTileUpperBound), mod(this.mX
				+ deltaX, mapTileUpperBound));
	}

	public Point withAntiTranslationMod(final int deltaY, final int deltaX,
			final int zoomLevel) {
		final int mapTileUpperBound = 1 << zoomLevel;
		return new Point(mod(this.mY - deltaY, mapTileUpperBound), mod(this.mX
				- deltaX, mapTileUpperBound));
	}

	public Point withTranslation(final Point point) {
		return withTranslation(point.mY, point.mX);
	}

	public Point withAntiTranslation(final Point point) {
		return withTranslation(point.mY, point.mX);
	}

	public Point withTranslationMod(final Point point, final int zoomLevel) {
		return withTranslationMod(point.mY, point.mX, zoomLevel);
	}

	public Point withAntiTranslationMod(final Point point, final int zoomLevel) {
		return withTranslationMod(point.mY, point.mX, zoomLevel);
	}

	protected static int mod(int number, final int modulus) {
		if (number > 0)
			return number % modulus;

		while (number < 0)
			number += modulus;

		return number;
	}

	public void show() {
		System.out.println(this.toString());
	}
}
